package com.jlwl.houseservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jlwl.houseservice.entity.Employee;
import com.jlwl.houseservice.entity.EmployeeSchedule;
import com.jlwl.houseservice.mapper.EmployeeMapper;
import com.jlwl.houseservice.service.EmployeeScheduleService;
import com.jlwl.houseservice.service.EmployeeService;
import com.jlwl.houseservice.vo.EmployeeDetailVO;
import com.jlwl.houseservice.vo.EmployeeQueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 员工Service实现类
 */
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {

    @Autowired
    private EmployeeScheduleService employeeScheduleService;

    @Override
    public Page<Employee> pageList(EmployeeQueryVO queryVO) {
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(queryVO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(Employee::getName, queryVO.getKeyword())
                    .or()
                    .like(Employee::getPhone, queryVO.getKeyword())
            );
        }
        
        // 工作类型筛选
        if (StringUtils.hasText(queryVO.getJobType())) {
            queryWrapper.eq(Employee::getJobType, queryVO.getJobType());
        }
        
        // 性别筛选
        if (queryVO.getGender() != null) {
            queryWrapper.eq(Employee::getGender, queryVO.getGender());
        }
        
        // 工作年限筛选
        if (queryVO.getWorkYears() != null) {
            queryWrapper.ge(Employee::getWorkYears, queryVO.getWorkYears());
        }
        
        // 技能筛选
        if (StringUtils.hasText(queryVO.getSkill())) {
            queryWrapper.like(Employee::getSkills, queryVO.getSkill());
        }
        
        // 状态筛选
        if (queryVO.getStatus() != null) {
            queryWrapper.eq(Employee::getStatus, queryVO.getStatus());
        } else {
            // 默认只查询在职员工
            queryWrapper.eq(Employee::getStatus, 1);
        }
        
        // 默认按评分倒序排序
        queryWrapper.orderByDesc(Employee::getRating);
        
        // 分页查询
        return page(new Page<>(queryVO.getPage(), queryVO.getSize()), queryWrapper);
    }

    @Override
    public EmployeeDetailVO getEmployeeDetail(Integer id) {
        // 获取员工信息
        Employee employee = getById(id);
        if (employee == null) {
            return null;
        }
        
        // 解析技能列表
        List<String> skillList = null;
        if (StringUtils.hasText(employee.getSkills())) {
            skillList = Arrays.asList(employee.getSkills().split(","));
        }
        
        // 获取服务统计
        Map<String, Object> serviceStats = getServiceStats(id);
        
        // 获取评价统计
        Map<String, Object> reviewStats = getReviewStats(id);
        
        // 获取近期排班
        List<Map<String, Object>> recentSchedules = getRecentSchedules(id);
        
        // 构建返回结果
        EmployeeDetailVO detailVO = new EmployeeDetailVO();
        detailVO.setEmployee(employee);
        detailVO.setSkillList(skillList);
        detailVO.setServiceStats(serviceStats);
        detailVO.setReviewStats(reviewStats);
        detailVO.setRecentSchedules(recentSchedules);
        
        return detailVO;
    }

    @Override
    @Transactional
    public boolean createEmployee(Employee employee) {
        // 设置初始值
        employee.setRating(new BigDecimal("5.0"));
        employee.setServiceCount(0);
        employee.setStatus(1); // 默认在职
        employee.setCreatedAt(LocalDateTime.now());
        employee.setUpdatedAt(LocalDateTime.now());
        
        return save(employee);
    }

    @Override
    @Transactional
    public boolean updateEmployee(Employee employee) {
        Employee existEmployee = getById(employee.getId());
        if (existEmployee == null) {
            return false;
        }
        
        employee.setUpdatedAt(LocalDateTime.now());
        
        return updateById(employee);
    }

    @Override
    @Transactional
    public boolean deleteEmployee(Integer id) {
        return removeById(id);
    }

    @Override
    @Transactional
    public boolean updateEmployeeStatus(Integer id, Integer status) {
        return update(new LambdaUpdateWrapper<Employee>()
                .eq(Employee::getId, id)
                .set(Employee::getStatus, status)
                .set(Employee::getUpdatedAt, LocalDateTime.now()));
    }

    @Override
    public List<Employee> getEmployeesByJobType(String jobType) {
        return list(new LambdaQueryWrapper<Employee>()
                .eq(Employee::getJobType, jobType)
                .eq(Employee::getStatus, 1)
                .orderByDesc(Employee::getRating));
    }

    @Override
    public List<Employee> getRecommendEmployees(Integer limit) {
        return list(new LambdaQueryWrapper<Employee>()
                .eq(Employee::getStatus, 1)
                .orderByDesc(Employee::getRating)
                .orderByDesc(Employee::getServiceCount)
                .last("LIMIT " + limit));
    }

    @Override
    @Transactional
    public boolean incrementServiceCount(Integer id) {
        return update(new LambdaUpdateWrapper<Employee>()
                .eq(Employee::getId, id)
                .setSql("service_count = service_count + 1")
                .set(Employee::getUpdatedAt, LocalDateTime.now()));
    }

    @Override
    @Transactional
    public boolean updateEmployeeRating(Integer id, Double rating) {
        Employee employee = getById(id);
        if (employee == null) {
            return false;
        }
        
        // 计算新的平均评分
        BigDecimal currentRating = employee.getRating();
        int serviceCount = employee.getServiceCount();
        
        BigDecimal newRating;
        if (serviceCount == 0) {
            newRating = new BigDecimal(rating);
        } else {
            // 计算加权平均
            BigDecimal totalScore = currentRating.multiply(new BigDecimal(serviceCount));
            totalScore = totalScore.add(new BigDecimal(rating));
            newRating = totalScore.divide(new BigDecimal(serviceCount + 1), 1, BigDecimal.ROUND_HALF_UP);
        }
        
        return update(new LambdaUpdateWrapper<Employee>()
                .eq(Employee::getId, id)
                .set(Employee::getRating, newRating)
                .set(Employee::getUpdatedAt, LocalDateTime.now()));
    }
    
    /**
     * 获取服务统计
     */
    private Map<String, Object> getServiceStats(Integer employeeId) {
        Employee employee = getById(employeeId);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalServices", employee.getServiceCount());
        stats.put("rating", employee.getRating());
        
        // 这里可以添加更多统计数据，如月度服务次数、年度服务次数等
        // 需要根据实际业务需求进行扩展
        
        return stats;
    }
    
    /**
     * 获取评价统计
     */
    private Map<String, Object> getReviewStats(Integer employeeId) {
        // 这里应该从评价表中获取数据
        // 由于评价功能尚未实现，这里返回模拟数据
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalReviews", 0);
        stats.put("goodReviews", 0);
        stats.put("badReviews", 0);
        
        return stats;
    }
    
    /**
     * 获取近期排班
     */
    private List<Map<String, Object>> getRecentSchedules(Integer employeeId) {
        // 获取未来7天的排班
        LocalDate startDate = LocalDate.now();
        LocalDate endDate = startDate.plusDays(7);
        
        List<EmployeeSchedule> schedules = employeeScheduleService.getEmployeeSchedules(employeeId, startDate, endDate);
        
        return schedules.stream().map(schedule -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", schedule.getId());
            map.put("date", schedule.getScheduleDate());
            map.put("timeSlots", schedule.getTimeSlots());
            map.put("status", schedule.getStatus());
            map.put("orderNo", schedule.getOrderNo());
            return map;
        }).collect(Collectors.toList());
    }
} 